/**
 * Looker 新闻整合项目
 * @author solosky
 */
package net.looker.work;

import net.looker.util.BlockQueue;

/**
 * 实现线程池
 * 用于维持服务器线程数量，防止产生很多的并发线程
 * @author solosky
 *
 */
public class WorkerPool 
{
	/**
	 * 空闲的工作者队列
	 */
	private BlockQueue<Worker> idleWorkerQueue;
	
	/**
	 * 所有的工作者列表
	 */
	private Worker[] allWorkerList;
	
	
	/**
	 * 构造函数，建立工作池
	 */
	public WorkerPool(int maxWorkerNum)
	{
		//至少有一个工作者
		maxWorkerNum = maxWorkerNum>0 ? maxWorkerNum : 1;
		
		//建立空闲工作者队列
		idleWorkerQueue = new BlockQueue<Worker>(maxWorkerNum);
		//建立所有的工作者
		allWorkerList   = new Worker[maxWorkerNum];
		//都没有工作，将所有的工作者添加到空闲的工作者的队列中
		for (int i=0; i<allWorkerList.length; i++)
			allWorkerList[i] = new Worker(idleWorkerQueue);
	}
	
	/**
	 * 返回一个空闲的工作者
	 * 如果没有就一直等待
	 * @return Worker
	 * @throws InterruptedException 
	 */
	public Worker getIdleWorker() throws InterruptedException
	{
		return idleWorkerQueue.remove();
	}
	
	/**
	 * 执行工作
	 * @param Work
	 * @throws InterruptedException 
	 */
	public void assignWork(Work work) throws InterruptedException
	{
		idleWorkerQueue.remove().assignWork(work);
	}
	
	/**
	 * 友好的关闭线程池
	 * 这个方法会等待所有的线程结束，然后中断所有的线程
	 * @throws InterruptedException 
	 */
	public void shutdown() throws InterruptedException
	{
		//等待所有的工作完成
		idleWorkerQueue.waitUntilFull();
		//中断所有的工作线程
		for (int i=0; i<allWorkerList.length; i++){
			allWorkerList[i].stopWork();
		}
	}
}
